#include "RemoteControl.h"

/* CONSTRUCTOR */
RemoteControl::RemoteControl(RemoteControlData remoteControlData)
{
  for(int i=0; i<NB_OF_SWITCH_RAILS; i++)
  {
    m_switchRails[i] = new SwitchRail(this, *(remoteControlData.switchRailsData[i]));
  }
  for(int i=0; i<NB_OF_TRAINS; i++)
  {
    m_trains[i] = new Train(this, *(remoteControlData.trainData[i]));
  }
  m_communication = Communication::add(&Serial1, this);
}

/* METHODES */

/**
* \brief Processing for switch rail evolution
* \param switchRailId, value
* \return none
*/
void RemoteControl::switchRailHasChanged(byte switchRailId, byte value)
{
  m_communication->sendCommand(new Command(CommandType::SWITCHRAIL_POSITION_UPDATE, switchRailId, value));
}

/**
* \brief Processing for train speed evolution
* \param trainId, value
* \return none
*/
void RemoteControl::trainSpeedHasChanged(byte trainId, boolean moveForward, byte value)
{
  Serial.print("0x");
  Serial.print(trainId);
  Serial.print(" 0x");
  Serial.print(moveForward);
  Serial.print(" 0x");
  Serial.print(value);
  Serial.println();
  if (value == 0x00)
  {
    m_communication->sendCommand(new Command(CommandType::TRAIN_SPEED_STOP_UPDATE, trainId, value));
  }
  else
  {
    if (moveForward == true)
    {
      m_communication->sendCommand(new Command(CommandType::TRAIN_SPEED_MOVE_FORWARD_UPDATE, trainId, value));
    }
    else
    {
      m_communication->sendCommand(new Command(CommandType::TRAIN_SPEED_MOVE_BACKWARD_UPDATE, trainId, value));
    }
  }
}

/**
* \brief Processing for train smoke evolution
* \param trainId, value
* \return none
*/
void RemoteControl::trainSmokeHasChanged(byte trainId, byte value)
{

}


/* Functions called by distant element */

/**
* \brief Inform the train that its speed command is accepted
* \param trainId
* \return none
*/
void RemoteControl::trainSpeedCommandAccepted(byte trainId)
{

}

/**
* \brief Inform the train that its speed command is adapted
* \param trainId
* \return none
*/
void RemoteControl::trainSpeedCommandAdapted(byte trainId)
{

}

/**
* \brief Inform the swith rail that its command is accepted
* \param switchRailId
* \return none
*/
void RemoteControl::switchRailCommandAccepted(byte switchRailId)
{

}

/**
* \brief Inform the swith rail that its command is delayed
* \param switchRailId
* \return none
*/
void RemoteControl::switchRailCommandDelayed(byte switchRailId)
{

}

/**
* \brief Analyse a command received over serial port
* \param command
* \return none
*/
void RemoteControl::commandReceived(Command* command)
{
  byte commandType = command->getType();
  byte commandDeviceId = command->getDeviceId();
  byte commandValue = command->getValue();
  int index;
  
  switch (commandType)
  {
    case CommandType::SWITCHRAIL_POSITION_UPDATE:
    case CommandType::SWITCHRAIL_POSITION_UPDATE_ACK:
      index = getSwitchRailIndexFromId(commandDeviceId);
      if (index == -1)
      {
        /* error... */
      }
      else
      {
        if (commandValue == CommandStatus::ACCEPTED)
        {
          m_switchRails[index]->switchRailCommandAccepted();
        }
        else
        {
          if (commandValue == CommandStatus::DELAYED)
          {
            m_switchRails[index]->switchRailCommandDelayed();
          }
          else
          {
            /* Unknown Command Status */
          }
        }
      }
      break;
    
    default:
      break;
  }
}

/**
* \brief Get the switch rail index from Id
* \param Id
* \return index
*/
int RemoteControl::getSwitchRailIndexFromId(byte id)
{
  int index = -1;                              // Initialize index
  for(int i=0; i<NB_OF_SWITCH_RAILS; i++) {
    if(m_switchRails[i]->getId() == id) {
      index = i;
      break;
    }
    else {
      /* not the correct switchRail, continue */
    }
  }
  return index;
}



